﻿define([
    'Wjs/Wjs'
],
function () {
    'use strict';

    // The selector manages the selection of the container view (grid, list, tree, etc)
    return Wjs.defineOnce({

        type: 'Selector',

        internal: {

            initialize: function () {              
      
                this.selection = []; // Store the selected items
     
                this.initialSelection = []; // Track changes
            }
        },

        setMultipleSelection: function (multipleSelection) {

            this.multipleSelection = multipleSelection;

            return this;
        },

        onSelectionChanged: function (fcn) {

            this.selectionChangedHandler = Wjs.chain(this.selectionChangedHandler, fcn);

            return this;
        },

        onBeforeSelect: function (fcn) {

            this.beforeSelectHandler = Wjs.chain(this.beforeSelectHandler, fcn);

            return this;
        },

        // Set up the selector on a child view
        setupSelector: function (child) {

            if (child.setSelector) { // It might be a nested view and it does not have the setSelector method

                child.setSelector(this);
            }
            else { // Assume it is a container view so pass this selector

                child.selector = this;

                if (!child.down) { // Leaf child

                    return;
                }

                child.down().forEach(function (ch) {

                    if (ch.setSelector) { // It might be a nested container view and it does not have the setSelector method

                        ch.setSelector(this);
                    }
                },
                this);
            }
        },

        // Selects the item performing other actions according to the options
        select: function (item, options) {

            if (this.beforeSelectHandler &&

                this.beforeSelectHandler(item) === false) { // Cancel the selection if returned false

                return;
            }

            this.selection.push(item);

            options = options || {};

            if (options.acceptChanges) {

                this.acceptChanges();
            }

            if (this.selectionChangedHandler) {

                this.selectionChangedHandler({
                    selectionType: 'select',
                    currentSelection: this.selection.slice(0),
                    initialSelection: this.initialSelection.slice(0),
                    fireFieldChanged: options.fireFieldChanged
                });
            }
        },

        // Deselects the item
        deselect: function (item, options) {
            var i;

            options = options || {};

            if (this.multipleSelection) {

                i = this.selection.indexOf(item);

                this.selection.splice(i, 1); // Remove the row from the selection
            }
            else { // Single selection

                this.selection.pop(); // Remove the first element of the array (we assume there can be only one element so this should empty the array)
            }

            if (this.selectionChangedHandler) {

                this.selectionChangedHandler({
                    selectionType: 'deselect',
                    currentSelection: this.selection.slice(0),
                    initialSelection: this.initialSelection.slice(0),
                    fireFieldChanged: options.fireFieldChanged
                });
            }
        },

        selectMultiple: function (items) {


        },

        deselectAll: function (options) {
            this.selection.length = 0;

            if (this.selectionChangedHandler) {

                this.selectionChangedHandler({
                    selectionType: 'deselectAll',
                    currentSelection: this.selection.slice(0),
                    initialSelection: this.initialSelection.slice(0),
                    fireFieldChanged: options.fireFieldChanged
                });
            }
        },

        // Copies the array to avoid modifying the existing selection
        getSelection: function () {

            return this.selection.slice(0); // Clone the array
        },

        // Compares the selection and initial selection arrays to notify that something has changed
        isModified: function () {
            var selection = this.selection,
                initialSelection = this.initialSelection,
                i;

            if (selection.length != initialSelection.length) {

                return true;
            }

            selection.sort();

            initialSelection.sort();

            for (i = 0; i < selection.length; ++i) {

                if (selection[i] != initialSelection[i]) {

                    return true;
                }
            }

            return false;
        },

        // Copies the items from the selection to the initial selection array so the isModified returns false while keeping the current selection
        acceptChanges: function () {
            var selection = this.selection,
                initialSelection = this.initialSelection,
                i;

            initialSelection.length = 0; // Reset the array

            for (i = 0; i < selection.length; ++i) {

                initialSelection[i] = selection[i];
            }
        },

        // Copies the items from the initial selection to the selection array so the selection is rolled back to its (last accepted) initial state
        rejectChanges: function () {
            var selection = this.selection,
                initialSelection = this.initialSelection,
                i;

            selection.length = 0; // Reset the array

            for (i = 0; i < initialSelection.length; ++i) {

                selection[i] = initialSelection[i];
            }
        }
    });

});